package cn.demoncat.util.websocket.util;

import cn.demoncat.util.lang.constant.StatusConstant;
import cn.demoncat.util.lang.entity.Result;
import cn.demoncat.util.web.TokenUtil;
import cn.demoncat.util.websocket.entity.UserSession;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.websocket.Session;
import java.io.IOException;
import java.util.List;

/**
 * WS工具
 * 
 * @author 延晓磊
 *
 * @since 2019年7月1日
 */
public class WebSocketUtil {

	private static final Logger LOG = LoggerFactory.getLogger(WebSocketUtil.class);

	/**
	 * 发送消息
	 * 
	 * @param session
	 * @param msg
	 * 
	 * @return true成功，false失败
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年7月1日
	 */
	public static boolean send(Session session, Result msg) {
		return send(session, msg.toJson());
	}

	/**
	 * 发送消息（异步）
	 *
	 * @param session
	 * @param msg
	 *
	 * @return true成功，false失败
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年7月1日
	 */
	public static boolean sendAsync(Session session, Result msg) {
		return sendAsync(session, msg.toJson());
	}

	/**
	 * 发送消息
	 * 
	 * @param session
	 * @param msg
	 * 
	 * @return true成功，false失败
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年7月1日
	 */
	public static boolean send(UserSession session, Result msg) {
		return send(session.getSession(), msg);
	}

	/**
	 * 发送消息（异步）
	 *
	 * @param session
	 * @param msg
	 *
	 * @return true成功，false失败
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年7月1日
	 */
	public static boolean sendAsync(UserSession session, Result msg) {
		return sendAsync(session.getSession(), msg);
	}

	/**
	 * 发送消息
	 * 
	 * @param session
	 * @param msg
	 * 
	 * @return true成功，false失败
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年7月1日
	 */
	public static boolean send(UserSession session, String msg) {
		return send(session.getSession(), msg);
	}

	/**
	 * 发送消息（异步）
	 *
	 * @param session
	 * @param msg
	 *
	 * @return true成功，false失败
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年7月1日
	 */
	public static boolean sendAsync(UserSession session, String msg) {
		return sendAsync(session.getSession(), msg);
	}

	/**
	 * 发送消息
	 *
	 * @param session
	 * @param msg
	 *
	 * @return true成功，false失败
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年7月1日
	 */
	public static boolean send(Session session, String msg) {
		if (session != null && session.isOpen()) {
			try {
				// 同步发送
				session.getBasicRemote().sendText(msg);
			} catch (IOException e) {
				LOG.warn("发送WebSocket消息失败：session = {}, status = {}, msg = {}", session.getId(), StatusConstant.Common.check(session.isOpen()), msg, e);
				return false;
			}
			return true;
		}else {
			return false;
		}
	}

	/**
	 * 发送消息（异步）
	 *
	 * 注意：适用于短消息，可能会报错 TEXT_FULL_WRITING，需要增加缓存区 websocket.text-buffer
	 *
	 * @param session
	 * @param msg
	 *
	 * @return true成功，false失败
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年7月1日
	 */
	public static boolean sendAsync(Session session, String msg) {
		if (session != null && session.isOpen()) {
			try {
				session.getAsyncRemote().sendText(msg);
			} catch (Exception e) {
				LOG.warn("异步发送WebSocket消息失败：session = {}, status = {}, msg = {}", session.getId(), StatusConstant.Common.check(session.isOpen()), msg, e);
				return false;
			}
			return true;
		}else {
			return false;
		}
	}

	/**
	 * 获取Token参数
	 * 
	 * @param session
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年7月1日
	 */
	public static String getToken(Session session) {
		return getParam(session, TokenUtil.TOKEN_KEY);
	}
	
	/**
	 * 获取参数
	 * 
	 * @param session
	 * @param param
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年7月1日
	 */
	public static String getParam(Session session, String param) {
		List<String> params = session.getRequestParameterMap().get(param);
		if (CollectionUtils.isNotEmpty(params)) {
			return params.get(0);
		}
		return null;
	}
	
	/**
	 * 获取Token参数
	 * 
	 * @param session
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年7月1日
	 */
	public static String getToken(UserSession session) {
		return getToken(session.getSession());
	}
	
	/**
	 * 获取参数
	 * 
	 * @param session
	 * @param param
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年7月1日
	 */
	public static String getParam(UserSession session, String param) {
		return getParam(session.getSession(), param);
	}
}
